package com.mailbox.mailbox.config.websocketConfig;

import com.alibaba.fastjson.JSON;
import com.mailbox.mailbox.domain.OnlineUser;
import com.mailbox.mailbox.mapper.ReceptionMapper;
import com.mailbox.mailbox.service.ReceptionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * WebSocketServer其实就相当于一个ws协议的Controller
// * @author 14455
 */
@Slf4j
@Component
@ServerEndpoint("/websocket/{userId}")
public class WebSocketMessageServer {

    /**
     * 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
     */
    private static int onlineCount = 0;
    //用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketMessageServer> webSocketSet = new CopyOnWriteArraySet<WebSocketMessageServer>();
    /**
     * concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
     */
    private static ConcurrentHashMap<Integer, Session> webSocketMap = new ConcurrentHashMap<>();
    /**
     * 与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    private Session session;
    /**
     * 接收userId
     */
    private Integer userId;

    public static ReceptionService receptionService;

    public static Map<String, OnlineUser> clients = new ConcurrentHashMap<>();

    @Resource
    private ReceptionMapper receptionMapper;

    @OnOpen
    public void OnOpen(Session session, @PathParam("userId") Integer userId) {
        this.session = session;
        this.userId = userId;
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            webSocketMap.put(userId, session);
            webSocketSet.add(this);
        } else {
            webSocketMap.put(userId, session);
            webSocketSet.add(this);
            addOnlineCount();
        }
        clients.put(String.valueOf(userId), new OnlineUser(userId, session));
    }

    @OnClose
    public void onClose() {
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            subOnlineCount();
        }
        clients.remove(userId);
    }

    /**
     * 客户端发送消息
     */
//    @OnMessage
//    public void onMessage(String message) {
//        log.info(message);
//        ObjectMapper objectMapper = new ObjectMapper();
//        Message chatMsg;
//        if (message != null) {
//            try {
//                chatMsg = objectMapper.readValue(message, Message.class);
//                //心跳
//                if (chatMsg.getToUser() == 0 && chatMsg.getFromUser() == 0) {
//                    return;
//                }
//                chatMsg.setIsLast(1);
//                LocalDateTime now = LocalDateTime.now();
//                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//                chatMsg.setDateTime(formatter.format(now));
//                Users user = chatService.queryUser(userId);
//                if ("admin".equals(user.getRoles()) && chatMsg.getToUser() == 0) {
//                    sendMessage(chatMsg);
//                } else {
//                    Session fromSession = webSocketMap.get(chatMsg.getFromUser());
//                    Session toSession = webSocketMap.get(chatMsg.getToUser());
//                    //声明一个map，封装直接发送信息数据返回前端
//                    Map<String, Object> resultMap = new HashMap<>();
//                    resultMap.put("fromUserId", chatMsg.getFromUser());
//                    resultMap.put("sendUser", chatMsg.getNickname());
//                    resultMap.put("content", chatMsg.getContent());
//                    resultMap.put("sendTime", chatMsg.getDateTime());
//                    resultMap.put("userImg", chatMsg.getAvatar());
//                    resultMap.put("toUserId", chatMsg.getToUser());
//                    JSONObject json = new JSONObject(resultMap);
//                    //发送给接收者.
//                    fromSession.getAsyncRemote().sendText(json.toString());
//                    if (toSession != null && toSession.isOpen()) {
//                        //发送给发送者.
//                        System.out.println("收到了！！！");
//                        toSession.getAsyncRemote().sendText(json.toString());
//                    }
//                    chatService.saveMessage(chatMsg);
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//    }

    /**
     * 错误
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
        error.printStackTrace();
    }

    /**
     * 实现推送功能
     */
//    public void sendMessage(Message chatMsg) throws IOException {
//
////        chatService.savePushMessage(chatMsg);
//        List<Integer> ids = chatService.allIds();
//        chatService.updateLast(ids, userId);
//        Map<String, Object> resultMap = new HashMap<>();
//        resultMap.put("sendUser", chatMsg.getNickname());
//        resultMap.put("content", chatMsg.getContent());
//        resultMap.put("sendTime", chatMsg.getDateTime());
//        resultMap.put("userImg", chatMsg.getAvatar());
//        resultMap.put("fromUserId", chatMsg.getFromUser());
//        JSONObject json = new JSONObject(resultMap);
//        this.session.getAsyncRemote().sendText(json.toString());
//        for (Integer id : ids) {
//            chatMsg.setToUser(id);
//            Session toSession = webSocketMap.get(id);
//            if (toSession != null && toSession.isOpen()) {
//                //发送给发送者.
//                toSession.getAsyncRemote().sendText(json.toString());
//            }
//            chatService.savePushMessage(chatMsg);
//        }
//    }

    /**
     * 在线人数
     *
     * @return
     */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 在线人数+1
     */
    public static synchronized void addOnlineCount() {
        WebSocketMessageServer.onlineCount++;
    }

    /**
     * 在线人数-1
     */
    public static synchronized void subOnlineCount() {
        WebSocketMessageServer.onlineCount--;
    }


    /*消息推送使用*/
    private void sendMsg(String userId, String content) {
        // 判断用户是否在线, 在线发送消息推送
        if (clients.containsKey(userId)) {
            try {
                clients.get(userId).getSession().getBasicRemote().sendText(JSON.toJSONString(content));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public void send(String content) {
        // 发送消息给所有人
        Set<String> userIds = clients.keySet();
        for (String userIdss : userIds) {
            this.sendMsg(userIdss, content);
        }
    }

}
